#ifndef AEYECLIENTS_AEYESENSORSDK_INCLUDEDEV_SOCKETREADERDETAIL_HPP_
#define AEYECLIENTS_AEYESENSORSDK_INCLUDEDEV_SOCKETREADERDETAIL_HPP_

#include <cstddef>
#include <cstdint>
#include <string>

#ifdef _MSC_VER
#define _WINSOCKAPI_
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#else
#include <arpa/inet.h>
#include <unistd.h>
#endif

#include "AEyeExceptions.hpp"

#ifndef SO_REUSEPORT
#define SO_REUSEPORT 1
#endif

namespace aeye {

constexpr size_t UDP_BUF_LEN = 65536;

class Reader {
  sockaddr_in sensor_addr_int_{};
  sockaddr_in local_addr_int_{};
  int sockfd_ = -1;
  bool broadcast_mode_;

  int setNonblockingAttribute() const noexcept;
  int getSO_ERROR() const noexcept;

 public:
  Reader(const std::string &sensorAddr, uint16_t clientPort, uint16_t serverPort, bool broadcastMode);

  void start();
  void stop() noexcept;

  bool run_select(unsigned s, unsigned us, fd_set& readFlags) noexcept;
  int is_set(const fd_set& readFlags) const noexcept;
  bool validate_ip_addr(const sockaddr_in& src_addr) const noexcept;

  // returns 0 if recvfrom returned <= 0, otherwise returns recvfrom's value
  size_t receive_bytes(uint8_t *buf, sockaddr_in& src_addr) const noexcept;
  static bool find_marker(const char (&arr)[4]) noexcept;
};




}
#endif //AEYECLIENTS_AEYESENSORSDK_INCLUDEDEV_SOCKETREADERDETAIL_HPP_
